package com.tencent.protocol.pay_unifiedorder;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.Map.Entry;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * 统一下单返回内容
 * @author zhoufeng
 *
 */
public class UnifiedorderResponse {

	/**
	 *  返回状态码	return_code	(必填)	String(16)	
		SUCCESS/FAIL
		此字段是通信标识，非交易标识，交易是否成功需要查看result_code来判断
	 */
	private String return_code ;

	/**
	 * 返回信息	return_msg	(非必填)	String(128)	
	   返回信息，如非空，为错误原因
	   签名失败
	   参数格式校验错误
	 */
	private String return_msg ;

	/**
	 * 公众账号ID	appid	(必填)	String(32)	调用接口提交的公众账号ID
	 */
	private String appid ;

	/**
	 * 商户号	mch_id	(必填)	String(32)	调用接口提交的商户号
	 */
	private String mch_id ;

	/**
	 * 设备号	device_info	(非必填)	String(32)	调用接口提交的终端设备号，
	 */
	private String device_info ;

	/**
	 * 随机字符串	nonce_str	(必填)	String(32)	微信返回的随机字符串
	 */
	private String nonce_str ;

	/**
	 * 签名	sign	(必填)	String(32)	微信返回的签名，详见签名算法
	 */
	private String sign ;

	/**
	 * 业务结果	result_code	(必填)	String(16)	SUCCESS/FAIL
	 */
	private String result_code ;

	/**
	 * 错误代码	err_code	(非必填)	String(32)	详细参见第6节错误列表
	 */
	private String err_code ;

	/**
	 * 错误代码描述	err_code_des	(非必填)	String(128)	错误返回的信息描述
	 */
	private String err_code_des ;

	/**
	 * 交易类型	trade_type	(必填)	String(16)	调用接口提交的交易类型，取值如下：JSAPI，NATIVE，APP，详细说明见参数规定
	 */
	private String trade_type ;

	/**
	 * 预支付交易会话标识	prepay_id	(必填)	String(64)	微信生成的预支付回话标识，用于后续接口调用中使用，该值有效期为2小时
	 */
	private String prepay_id ;

	/**
	 * 二维码链接	code_url  (非必填)	String(64)	URl：weixin：//wxpay/s/An4baqw	trade_type为NATIVE是有返回，可将该参数值生成二维码展示出来进行扫码支付
	 */
	private String code_url ;

	public String getReturn_code() {
		return return_code;
	}

	public void setReturn_code(String return_code) {
		this.return_code = return_code;
	}

	public String getReturn_msg() {
		return return_msg;
	}

	public void setReturn_msg(String return_msg) {
		this.return_msg = return_msg;
	}

	public String getAppid() {
		return appid;
	}

	public void setAppid(String appid) {
		this.appid = appid;
	}

	public String getMch_id() {
		return mch_id;
	}

	public void setMch_id(String mch_id) {
		this.mch_id = mch_id;
	}

	public String getDevice_info() {
		return device_info;
	}

	public void setDevice_info(String device_info) {
		this.device_info = device_info;
	}

	public String getNonce_str() {
		return nonce_str;
	}

	public void setNonce_str(String nonce_str) {
		this.nonce_str = nonce_str;
	}

	public String getSign() {
		return sign;
	}

	public void setSign(String sign) {
		this.sign = sign;
	}

	public String getResult_code() {
		return result_code;
	}

	public void setResult_code(String result_code) {
		this.result_code = result_code;
	}

	public String getErr_code() {
		return err_code;
	}

	public void setErr_code(String err_code) {
		this.err_code = err_code;
	}

	public String getErr_code_des() {
		return err_code_des;
	}

	public void setErr_code_des(String err_code_des) {
		this.err_code_des = err_code_des;
	}

	public String getTrade_type() {
		return trade_type;
	}

	public void setTrade_type(String trade_type) {
		this.trade_type = trade_type;
	}

	public String getPrepay_id() {
		return prepay_id;
	}

	public void setPrepay_id(String prepay_id) {
		this.prepay_id = prepay_id;
	}

	public String getCode_url() {
		return code_url;
	}

	public void setCode_url(String code_url) {
		this.code_url = code_url;
	}


	/**
	 * 解析xml格式的内容，并将值填充到本实例
	 * @param xml
	 */
	public UnifiedorderResponse wrapFromXml(String xml){
		DocumentBuilderFactory factory = DocumentBuilderFactory   
				.newInstance();   
		Document doc;
		try {
			DocumentBuilder builder = factory.newDocumentBuilder();   
			doc = builder.parse(new ByteArrayInputStream(xml.getBytes()));
		} catch (ParserConfigurationException | SAXException | IOException  e  ) {
			e.printStackTrace();
			return this ;
		}
		Element root = doc.getDocumentElement();
		NodeList nodeList = root.getChildNodes();   
		String fieldName = null ;
		String fieldValue = null ;
		Class<?> clazz = this.getClass();
		Field classField = null ;
		for (int i = 0; i < nodeList.getLength(); i++) {
			Node field = nodeList.item(i); 
			fieldName = field.getNodeName() ;
			fieldValue = field.getTextContent();
			try {
				classField = clazz.getDeclaredField(fieldName) ;
				if( classField == null){
					continue ;
				}
				classField.setAccessible(true); 
				classField.set(this, fieldValue);
			} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { 
				continue ;
			}
		}
		return this ;
	}


	/**
	 * 将Map映射到本实例的字段上
	 * @param xml
	 */
	public UnifiedorderResponse wrapFromMap(Map<String,Object> map){
		String fieldName = null ;
		Object fieldValue = null ;
		Class<?> clazz = this.getClass();
		Field classField = null ;
		for (Entry<String, Object> mapEntry : map.entrySet()) {
			fieldName = mapEntry.getKey();
			fieldValue = mapEntry.getValue();
			try {
				classField = clazz.getDeclaredField(fieldName) ;
				if( classField == null){
					continue ;
				}
				classField.setAccessible(true); 
				classField.set(this, fieldValue);
			} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { 
				continue ;
			}
		}
		return this ;
	}


	@Override
	public String toString() {
		return "UnifiedorderResponse [return_code=" + return_code + ", return_msg=" + return_msg + ", appid=" + appid
				+ ", mch_id=" + mch_id + ", device_info=" + device_info + ", nonce_str=" + nonce_str + ", sign=" + sign
				+ ", result_code=" + result_code + ", err_code=" + err_code + ", err_code_des=" + err_code_des
				+ ", trade_type=" + trade_type + ", prepay_id=" + prepay_id + ", code_url=" + code_url + "]";
	}

}
